﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WMPLib;
using System.Windows.Forms;
using System.Drawing;
using System.IO;

namespace AlbunTest
{
    public class ID3TagReader
    {
        public ID3TagReader(IWMPMedia file)
        {
            media = (IWMPMedia3)file;
            
            Title = media.getItemInfo("Title");
            Artist = media.getItemInfo("Artist");
        }

        public string Title
        {
            get;
            private set;
        }

        public string Artist
        {
            get;
            private set;
        }

        public string Album
        {
            get
            {
                string info;
                try
                {
                    info = media.getItemInfo("Album");
                }
                catch
                {
                    info = "";
                }
                return info;
            }
        }

        public string Track
        {
            get
            {
                string info;
                try
                {
                    info = media.getItemInfo("WM/TrackNumber");
                }
                catch
                {
                    info = "";
                }
                return info;
            }
        }

        public string Genre
        {
            get
            {
                string info;
                try
                {
                    info = media.getItemInfo("Genre");
                }
                catch
                {
                    info = "";
                }
                return info;
            }
        }

        public string Year
        {
            get
            {
                string info;
                try
                {
                    info = media.getItemInfo("WM/Year");
                }
                catch
                {
                    info = "";
                }
                return info;
            }
        }

        // For some reason the Windows Media Player SDK does not allow access to
        // the image objects stored in the ID3 tag. You can query to see if they
        // exist, but you can't actually get the image. So, we just read in the
        // whole ID3 tag from the actual file, then look for an "APIC" frame
        // in the ID3 tag.
        public Image AlbumCover
        {
            get
            {
                // We should only have to read it in one time
                if (album_cover != null)
                {
                    return album_cover;
                }

                try
                {
                    // Check to make sure the media contains a picture
                    if (media.getAttributeCountByType("WM/Picture", "") > 0)
                    {
                        // Open the file
                        FileStream srcfile = new FileStream(media.sourceURL, FileMode.Open,
                            FileAccess.Read, FileShare.ReadWrite);

                        // Read the ID3 Tag into a buffer
                        byte[] id3tag = ReadID3Tag(srcfile);

                        // Find the offset in the buffer where the image starts
                        int imgoffset = FindImageOffset(id3tag);

                        // Make a stream that starts where the image starts
                        MemoryStream imgstream = new MemoryStream(id3tag, imgoffset,
                            id3tag.Length - imgoffset);

                        // Read in the image
                        album_cover = Image.FromStream(imgstream);
                    }
                    else
                    {
                        // If no image, load a default
                        album_cover = null;
                    }
                }
                catch
                {
                    // If an error occurs, load a default image
                    album_cover = null;
                }

                return album_cover;
            }
        }

        private byte[] ReadID3Tag(Stream stream)
        {
            // File should start with "ID3", this will be a problem if, for
            // some reason, the ID3 tag is not the first thing in the file
            byte[] header = new byte[10];
            stream.Read(header, 0, 10);
            if (header[0] != 0x49 || header[1] != 0x44 || header[2] != 0x33)
            {
                throw new Exception("Could not find ID3 Tag");
            }

            // Convert sync safe size to normal size
            int size;
            size = header[9] & 0x7f;
            size += (header[8] & 0x7f) << 7;
            size += (header[7] & 0x7f) << 14;
            size += (header[6] & 0x7f) << 21;

            // Read the whole ID3 tag into a buffer
            byte[] data = new byte[size];
            stream.Read(data, 0, size);
            return data;
        }

        private int FindImageOffset(byte[] tag)
        {
            // Look for APIC frame
            for (int i = 0; i < tag.Length - 64; i++)
            {
                if (tag[i] == 'A' && tag[i + 1] == 'P' && tag[i + 2] == 'I' && tag[i + 3] == 'C')
                {
                    // Advance past fixed size fields
                    i += 11;

                    // Advance past mime type string
                    for (; tag[i] != 0; i++) ;
                    i++;

                    // Advance past image type field
                    i++;

                    // Advance past image description string
                    for (; tag[i] != 0; i++) ;
                    i++;

                    return i;
                }
            }

            throw new Exception("Could not find Attached Picture (APIC) frame");
        }

        private IWMPMedia3 media;
        //private PlayerConfig config;
        private Image album_cover;
    }
}


